/*  
    distinct
    它能帮我们把相同值的资料滤掉只留一笔
*/

var source = Rx.Observable.from(['a', 'b', 'c', 'a', 'b'])
            .zip(Rx.Observable.interval(300), (x, y) => x);
var example = source.distinct()

example.subscribe({
    next: (value) => { console.log(value); },
    error: (err) => { console.log('Error: ' + err); },
    complete: () => { console.log('complete'); }
});
// a
// b
// c
// complete
/* 
    source : --a--b--c--a--b|
                distinct()
    example: --a--b--c------|
*/

/* 
    另外我们可以传入一个selector callback function，这个callback function 会传入一个接收到的元素，
    并回传我们真正希望比对的值，举例如下
*/

var source1 = Rx.Observable.from([{ value: 'a'}, { value: 'b' }, { value: 'c' }, { value: 'a' }, { value: 'c' }])
            .zip(Rx.Observable.interval(300), (x, y) => x);
var example1 = source1.distinct((x) => {
    // 数组中的所有项都会走到这个函数内
    console.log(x, 'x');
    
    return x.value //我们对比对象中的value属性的值来进行过滤重复的项
})

example1.subscribe({
    next: (value) => { console.log(value); }, // 此处只会输出数组中每个item对象中value值没重复的
    error: (err) => { console.log('Error: ' + err); },
    complete: () => { console.log('complete'); }
});
// {value: "a"}
// {value: "b"}
// {value: "c"}
// complete
/* 
    这里可以看到，因为source1 送出的都是对象，而js 对象的比对是比对记忆体位置，
    所以在这个例子中这些对象永远不会相等，但实际上我们想比对的是对象中的value，
    这时我们就可以传入selector callback，来选择我们要比对的值。
    
    实际上 distinct() 会在背地里建立一个Set，当接收到元素时会先去判断Set 内是否有相同的值，
    如果有就不送出，如果没有则存到Set 并送出。所以记得尽量不要直接把distinct 用在一个无限的observable 里，
    这样很可能会让Set 越来越大，建议大家可以放第二个参数flushes，或用distinctUntilChanged
*/